#ifndef _NTH_LIB_H
#include <nth-lib.h>
#endif

#ifndef _STDIO_H
#include <stdio.h>
#endif

#ifndef _STRING_H
#include <string.h>
#endif

int Clean_Nth_Plugin(
	struct Nth_Plugin * nth_plugin
){
	if (!nth_plugin){
		return NTH_ERROR_NULL_POINTER;
	}

	if (nth_plugin->plugin_name){
		free(nth_plugin->plugin_name);
		nth_plugin->plugin_name = 0;
	}

	if (nth_plugin->plugin_description){
		free(nth_plugin->plugin_description);
		nth_plugin->plugin_description = 0;
	}

	return 0;
}

int Initialize_Nth_Plugin(
	struct Nth_Plugin * nth_plugin
){
	char plugin_name[] = "file";
	char plugin_desc[] = "Get number from a file";

	if (!nth_plugin){
		return NTH_ERROR_NULL_POINTER;
	}

	nth_plugin->plugin_name = malloc(sizeof(plugin_name));

	if (!nth_plugin->plugin_name){
		return NTH_ERROR_NO_MEMORY;
	}

	memcpy(
		nth_plugin->plugin_name,
		plugin_name,
		sizeof(plugin_name)
	);

	nth_plugin->plugin_description = malloc(sizeof(plugin_desc));

	if (!nth_plugin->plugin_description){
		free(nth_plugin->plugin_name);
		nth_plugin->plugin_name = 0;
		return NTH_ERROR_NO_MEMORY;
	}

	memcpy(
		nth_plugin->plugin_description,
		plugin_desc,
		sizeof(plugin_desc)
	);

	nth_plugin->plugin_callback = Nth_Plugin_Callback;

	return 0;
}

int Nth_Plugin_Callback(
	struct Nth_Program * nth_program,
	struct Nth_Number * plugin_number
){
	int error = 0;
	char * file_name = 0;
	size_t file_size = 0;

	if (!nth_program){
		return NTH_ERROR_NULL_POINTER;
	}

	if (!plugin_number){
		return NTH_ERROR_NULL_POINTER;
	}

	error = Get_Next_Nth_Argument(
		nth_program,
		&file_name
	);

	if (error){

		Push_Nth_Failure(
			nth_program,
			"Nth_Plugin_Callback",
			"Failed to get file name"
		);

		return 1;
	}

	error = Iterate_Nth_Argument(
		nth_program
	);

	if (error){

		Push_Nth_Failure(
			nth_program,
			"Nth_Plugin_Callback",
			"Failed to iterate file name argument"
		);

		return 1;
	}

	error = Get_Nth_File_Size(
		file_name,
		&file_size
	);

	if (error){

		Push_Nth_Failure(
			nth_program,
			"Nth_Plugin_Callback",
			"Failed to get file size"
		);

		return 1;
	}

	error = Set_Nth_Number_Length(
		plugin_number,
		file_size
	);

	if (error){

		Push_Nth_Failure(
			nth_program,
			"Nth_Plugin_Callback",
			"Failed to set number length"
		);

		return 1;
	}

	error = Read_Nth_File(
		file_name,
		plugin_number->number_buffer,
		plugin_number->number_length
	);

	if (error){

		Push_Nth_Failure(
			nth_program,
			"Nth_Plugin_Callback",
			"Failed to read file"
		);

		return 1;
	}

	return 0;
}

